from Products.KnowledgeEngine.KERL.Tokens.Token import Token
from Products.KnowledgeEngine.KERL.Operators import Operator, SimpleOperator
from Products.KnowledgeEngine.KERL.KERLExceptions import *
from DateTime import DateTime

class InGroup(SimpleOperator):
    
    _opname = "ingroup"
    
    def execute(self, assessment):
        
        groupname   = self.b.getObject()
        context     = self.a.namespace['model']
        currentuser = context.portal_membership.getAuthenticatedMember()        
        groups      = currentuser.getGroups()
        
        #print "Got Groups: %s" % `groups`
        
        return (groupname in groups)
    
    def toEnglish(self):
        return self.a.toEnglish() + " is in group " + self.b.toEnglish()
    
    def toSQL(self):
        
        # User actions don't compile to SQL at all, but we can execute them and return True or False
        result = self.execute( assessment=None )
        if result is True:
            return "True"
        elif result == False:
            return "False"
        else:
            raise UnexpectedResult
        
            

class NotInGroup(InGroup):
    
    _opname = "notingroup"
    
    def execute(self, assessment):
        return not InGroup.execute(self, assessment)
    
    def toEnglish(self):
        return self.a.toEnglish() + " is not in group " + self.b.toEnglish() 
    
    
class HasRole(SimpleOperator):
    """ Does the specified user have the given role? 
    
        Example Usage: ['currentuser','hasrole','Manager']    
    """
    
    _opname = "hasrole"
    
    def execute(self, assessment):

        context     = self.a.namespace['model']
        currentuser = context.portal_membership.getAuthenticatedMember()        
        checkrole   = self.b.getObject()
        
        if (currentuser.has_role( checkrole )): # Note: Returns 1 or 0, we need to explicitly return True or False
            return True
        else:
            return False
    
    def toSQL(self):
        
        # User actions don't compile to SQL at all, but we can execute them and return True or False
        result = self.execute( assessment=None )
        if result is True:
            return "True"
        elif result == False:
            return "False"
        else:
            raise UnexpectedResult    
    

class Is(SimpleOperator):
    
    _opname = "is"
    
    def execute(self, assessment):
        
        context     = self.a.namespace['model']
        currentuser = context.portal_membership.getAuthenticatedMember()        
        checkUser   = self.b.getObject()
        
        if currentuser.getId() == checkUser:
            return True
        else:
            return False
        
    def toSQL(self):
        
        # User actions don't compile to SQL at all, but we can execute them and return True or False
        result = self.execute( assessment=None )
        if result is True:
            return "True"
        elif result == False:
            return "False"
        else:
            raise UnexpectedResult           
            
            
class IsNot(Is):
    def execute(self, assessment):
        return not Is.execute(self, assessment)
            

class CurrentUserToken(Token):
    
    operators = dict(Token.operators)
    operators.update({
        'ingroup'    : InGroup,     
        'notingroup' : NotInGroup,
        'hasrole'    : HasRole,     
        'is'         : Is,
        'isnot'      : IsNot,
    })
    
    def __init__(self, namespace):
        
        self.namespace = namespace
    
    def toEnglish(self):
        """ Compiles this token into english """
        
        return "Current User"
        
    def toKERL(self):
        return "'currentuser'"
        